package Data;

import GUI.AObserver;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;

/**
 * Je singleton, spojeni s db se tedy bude vytvaret pouze jednou v konstruktoru
 * @author Martin
 * @version 1.0
 * @created 14-III-2012 13:12:32
 */
public class RuleDB {

    private static RuleDB self = null;
    public DbData dbData;
    private Statement stat;
    private Connection conn;

    public RuleDB(ArrayList<AObserver> observers) {
        try {
            Class.forName("org.h2.Driver");
            conn = DriverManager.getConnection("jdbc:h2:./db");
            stat = conn.createStatement();
            vytvorDB();
        } catch (ClassNotFoundException ex) {
            self = null;
            chyba(observers);
        } catch (SQLException ex) {
            self = null;
            chyba(observers);
            System.out.println(ex.getMessage());
        }
    }
    
    private void vytvorDB() throws SQLException {
        //stat.execute("create table IF NOT EXISTS INFO(id int primary key auto_increment,river varchar(255),station varchar(255),Unique(river, station))");
        stat.execute("create table IF NOT EXISTS DATA(id int primary key auto_increment,time long(32760), river varchar(255),station varchar(255),flow float(53), Unique (time, river, station))");
    }

    public synchronized static RuleDB createInstance(ArrayList<AObserver> observers) {
        if (self == null) {
            self = new RuleDB(observers);
        }
        return self;
    }

    /**
     * 
     * @param to
     * @param from
     */
    public ArrayList<DbData> getData(Date from, Date to) {
        try {
            ResultSet rs = stat.executeQuery("select flow, time from DATA where time>="+from.getTime()+" and time <="+to.getTime()+"");
            ArrayList<DbData> result = new ArrayList<DbData>();
            while (rs.next()) {
               //System.out.println((new Date(rs.getLong("time"))).toString());
                result.add(new DbData(new Date(rs.getLong("time")),rs.getDouble("flow")));
            }
            return result;
        } catch (SQLException ex) {
            System.out.println(ex.getMessage());
            return null;
        }
    }

    /**
     * 
     * @param location
     * @param data
     */
    public boolean saveData(String river, String station, DbData data) {
        try {
            stat.execute("insert into DATA(time,flow,river,station) values('"+data.getDate().getTime()+"','"+data.getFlow()+"','"+river+"','"+station+"')");
            //stat.execute("insert into INFO(river,station) values('"+river+"','"+station+"')");
        } catch (SQLException ex) {
            //data jsou duplicitni nebo chyba!!
            //System.out.println(ex);
            //System.out.println("duplicita");
            return false;
        }
        return true;
    }

    private void chyba(ArrayList<AObserver> observers) {
        for (AObserver observer : observers) {
            observer.messageDatabaze("Nastala chyba při práci s databází");
            //m_AObserver;
        }
    }

    public void end(ArrayList<AObserver> observers) {
        try {
            stat.close();
            conn.close();
        } catch (SQLException ex) {
            chyba(observers);
        }
        stat = null;
        conn = null;
    }
}